When you use the Bison declaration {fCode}%pure\_parser{f} to request a
pure, reentrant parser, the global communication variables {fCode}yylval{f}
and {fCode}yylloc{f} cannot be used. (\*Note <Pure Decl=>PureDecl>: A Pure (Reentrant) Parser.) In such parsers the two global variables are replaced by
pointers passed as arguments to {fCode}yylex{f}. You must declare them as
shown here, and pass the information back by storing it through those
pointers.
#Wrap off
#fCode
yylex (lvalp, llocp)
YYSTYPE \*lvalp;
YYLTYPE \*llocp;
\{
…
\*lvalp = value; \/\* Put value onto Bison stack. \*\/
return INT; \/\* Return the type of the token. \*\/
…
\}
#f
#Wrap on
If the grammar file does not use the {fEmphasis}@{f} constructs to refer to
textual positions, then the type {fCode}YYLTYPE{f} will not be defined. In
this case, omit the second argument; {fCode}yylex{f} will be called with
only one argument.
You can pass parameter information to a reentrant parser in a reentrant
way. Define the macro {fCode}YYPARSE\_PARAM{f} as a variable name. The
resulting {fCode}yyparse{f} function then accepts one argument, of type
{fCode}void \*{f}, with that name.
When you call {fCode}yyparse{f}, pass the address of an object, casting the
address to {fCode}void \*{f}. The grammar actions can refer to the contents
of the object by casting the pointer value back to its proper type and
then dereferencing it. Here's an example. Write this in the parser:
#Wrap off
#fCode
%\{
struct parser\_control
\{
int nastiness;
int randomness;
\};
\#define YYPARSE\_PARAM parm
%\}
#f
#Wrap on
Then call the parser like this:
#Wrap off
#fCode
struct parser\_control
\{
int nastiness;
int randomness;
\};
…
\{
struct parser\_control foo;
… \/\* Store proper data in {fCode}foo{f}. \*\/
value = yyparse ((void \*) &foo);
…
\}
#f
#Wrap on
In the grammar actions, use expressions like this to refer to the data:
#Wrap off
#fCode
((struct parser\_control \*) parm)->randomness
#f
#Wrap on
If you wish to pass the additional parameter data to {fCode}yylex{f},
define the macro {fCode}YYLEX\_PARAM{f} just like {fCode}YYPARSE\_PARAM{f}, as
shown here:
#Wrap off
#fCode
%\{
struct parser\_control
\{
int nastiness;
int randomness;
\};
\#define YYPARSE\_PARAM parm
\#define YYLEX\_PARAM parm
%\}
#f
#Wrap on
You should then define {fCode}yylex{f} to accept one additional
argument---the value of {fCode}parm{f}. (This makes either two or three
arguments in total, depending on whether an argument of type
{fCode}YYLTYPE{f} is passed.) You can declare the argument as a pointer to
the proper object type, or you can declare it as {fCode}void \*{f} and